package com.unytech.project.web.interceptor;

import java.lang.reflect.Method;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.unytech.project.annotation.ActionMethodLabel;
import com.unytech.project.annotation.enumerate.InterceptLevel;
import com.unytech.project.common.Globals;
import com.unytech.project.common.enumerate.YesorNo;
import com.unytech.project.entity.system.Permission;
import com.unytech.project.utils.SystemParams;
import com.unytech.project.web.action.ActionResult;

public class DefaultSystemInterceptor extends AbstractInterceptor {
	final private Log logger = LogFactory.getLog(getClass());
	@Resource private SystemParams systemParams;

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		/**
		 * 因为默认拦截器是无法定义是否拦截某个方法的，所以这里要做判断，
		 * 不拦截一些非页面级的请求方法（请求验证码），和返回值为NULL的方法（AJAX请求的方法）
		 * AJAX请求的方法返回值都为NULL，但要做特殊的控制
		 */
		logger.info("-----进入系统拦截器-----");
		ActionProxy ap = invocation.getProxy();
		ActionContext act = invocation.getInvocationContext();
		

		
		StringBuffer requesturi = new StringBuffer();
		requesturi.append(ap.getNamespace()).append("/").append(ap.getActionName()); 
		
		Method method = ap.getAction().getClass().getMethod(ap.getMethod(), null);
		if (method != null) {
			ActionMethodLabel abl = method.getAnnotation(ActionMethodLabel.class);
			
			//检测拦截定义
			if (abl == null) {
				act.getSession().put(Globals.SESSION_MESSAGE_KEY, "未定义此请求的拦截级别，请联系管理员！");
				return ActionResult.MESSAGE_VIEW;
			}
			
			//一级拦截
			if (abl.intercept().equals(InterceptLevel.PUBLIC)) {
				logger.info("系统拦截器：不对此方法的请求进行拦截:"+ap.getMethod());
				return invocation.invoke();
			}
			
			//二级拦截
			if (abl.intercept().equals(InterceptLevel.INITSYSTEM)) {
				logger.info("系统拦截器：检测系统是否已经初始化");
				if (systemParams.getSysteminitstate().equals(YesorNo.NO.toString().toLowerCase())) {
					act.getSession().put(Globals.SESSION_MESSAGE_KEY, "检测到系统还没有初始化，请先初始化系统！");
					return ActionResult.INITSYSTEM_VIEW;
				}
				if (ap.getMethod().equals("initSystem") && systemParams.getSysteminitstate().equals(YesorNo.YES.toString().toLowerCase())) {
					act.put(Globals.SESSION_MESSAGE_KEY, "检测到系统已经初始化，请勿重复初始化系统！");
					return ActionResult.MESSAGE_VIEW;
				}
			}
			
			//三级拦截
			if (abl.intercept().equals(InterceptLevel.PROTECTED)) {
				logger.info("系统拦截器：检测用户是否登录");
				//要处理AJAX方法拦截返回值
				if (act.getSession().get(Globals.SESSION_USERINSESSION_KEY) == null) {
					act.getSession().put(Globals.SESSION_MESSAGE_KEY, "您还没有登录，请先登录！");
					return Action.LOGIN;
				}
			}
			
			//四级拦截
			if (abl.intercept().equals(InterceptLevel.PRIVATE)) {
				logger.info("系统拦截器：检测用户是否拥有相应的请求权限");
				//要处理AJAX方法拦截返回值
				List<Permission> permlist = (List<Permission>) act.getSession().get(Globals.SESSION_USERPERMISSION_KEY);
				if (permlist == null || permlist.size() == 0) {
					act.getSession().put(Globals.SESSION_MESSAGE_KEY, "没有找到任何的权限信息，请重新登录或者联系管理员！");
					return Action.LOGIN;
				}
				else
				{
					boolean hasperm = false;
					for (int i=0; i<permlist.size(); i++) {
						Permission perm = permlist.get(i);
						if (perm.getPermuri().equals(requesturi.toString())) {
							hasperm = true;
							return invocation.invoke(); 
						}
					}
					if (!hasperm) {
						act.getSession().put(Globals.SESSION_MESSAGE_KEY, "您没有此操作的权限，请联系管理员！");
						return Action.LOGIN;
					}	
				}
			}
		}
		

		

		
		//从ActionContext中得到HttpServletRequest
//		HttpServletRequest request = (HttpServletRequest) invocation.getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
		//取得所请求URI
//		String uri2 = request.getRequestURL().toString();  //因为考虑到此方法得到的uri会有很多不必要的方法，使用url的时候需要过滤，所以暂且不用
//		System.out.println("request的URL："+uri2);
		return invocation.invoke();
	}

}
